#include "dvc.h"
#include <stdlib.h>
#include <stdio.h>
#include "drv_iwdt.h"

/////////////////////////////////////////////////////////////////////////////
static float s_SecondCALI_p1=0.35/1000000,s_SecondCALI_p2=-0.15/ 1000000,s_SecondCALI_preVcm=0,s_SecondCALI_preVcell_2nd=0;
uint32_t Sigma_SecondCALI=0;
/**
	* @说明	AFE初始化配置写入P
	* @参数	寄存器自定义参数默认值
	* @返回值	成功/失败
	* @注	
*/
static bool DVC11XX_InitRegs(void){
	memcpy((char *)&g_AfeRegs+81,DVC11XX_PresetConfigRegData_R81To121,sizeof(DVC11XX_PresetConfigRegData_R81To121));
	return dvc11xx_write_regs(AFE_ADDR_R(81),sizeof(DVC11XX_PresetConfigRegData_R81To121));
}
/**
	* @说明	清除所有警报
	* @参数	
	* @返回值	
	* @注	
*/
void CleanError(void){
	g_AfeRegs.R0.cleanflag=0;
	while(!dvc11xx_write_regs(AFE_ADDR_R(0),1));
}
/**
	* @说明	GPIO初始化
	* @参数	
	* @返回值	
	* @注	
*/
void DVC11XX_GPIO_Init(void){
	
}

/**
	* @说明	GP1复用配置
	* @参数	uint8_t 控制位      0x00 关闭     0x01 热敏电阻检测输入    0x02 模拟电压输入	 0x03 充电驱动硬线控制
	* @返回值	
	* @注	
*/
void GP1_ModeConfig(uint8_t mode){
	if(mode<=4){
		g_AfeRegs.R116.GP1M=mode;
		dvc11xx_write_regs(AFE_ADDR_R(116),1);
	}
}
/**
	* @说明	GP2复用配置
	* @参数	uint8_t 控制位      0x00 关闭     0x01 热敏电阻检测输入    0x02 模拟电压输入	0x06 中断输出  0x07 预放低边输出
	* @返回值	
	* @注	
*/
void GP2_ModeConfig(uint8_t mode){
	if((mode<=7)&&!((mode>2)&&(mode<6))){
		g_AfeRegs.R116.GP2M=mode;
		dvc11xx_write_regs(AFE_ADDR_R(116),1);	
	}
}

/**
	* @说明	GP3复用配置
	* @参数	uint8_t 控制位      0x00 关闭     0x01 热敏电阻检测输入    0x02 模拟电压输入	0x06 中断输出  0x07 预充低边输出									
	* @返回值	
	* @注	
*/
void GP3_ModeConfig(uint8_t mode){
	if((mode<=7)&&!((mode>2)&&(mode<6))){
		g_AfeRegs.R116.GP3M=mode;
		dvc11xx_write_regs(AFE_ADDR_R(116),1);	
	}
}

/**
	* @说明	GP4复用配置
	* @参数	uint8_t 控制位     0x00 关闭    0x01 热敏电阻检测输入    0x02 模拟电压输入	0x03 放电驱动硬线控制								
	* @返回值	
	* @注	
*/
void GP4_ModeConfig(uint8_t mode){
	if(mode<=4){
		g_AfeRegs.R117.GP4M=mode;
		dvc11xx_write_regs(AFE_ADDR_R(117),1);	
	}
}

/**
	* @说明	GP5复用配置
	* @参数	uint8_t 控制位      0x00 关闭     0x01 热敏电阻检测输入    0x02 模拟电压输入	0x06 中断输出  0x07 充电低边输出								
	* @返回值	
	* @注	
*/
void GP5_ModeConfig(uint8_t mode){
	if((mode<=7)&&!((mode>2)&&(mode<6))){
		g_AfeRegs.R117.GP5M=mode;
		dvc11xx_write_regs(AFE_ADDR_R(117),1);	
	}
}

/**
	* @说明	GP6复用配置
	* @参数	uint8_t 控制位      0x00 关闭     0x01 热敏电阻检测输入    0x02 模拟电压输入	 0x06 中断输出  0x07 放电低边输出								
	* @返回值	
	* @注	
*/
void GP6_ModeConfig(uint8_t mode){
	if((mode<=7)&&!((mode>2)&&(mode<6))){
		g_AfeRegs.R117.GP6M=mode;
		dvc11xx_write_regs(AFE_ADDR_R(117),1);	
	}
}

/**
	* @说明	GP脚模拟电压输入计算
	* @参数	uint8_t GP脚
	* @返回值	uint16_t 电压值
	* @注	
*/
bool afe_crc_err_bit = 0;
float GPn_Analog_Input_voltage(uint8_t GP){
	float temp_voltage;
	uint16_t GP_value;
		dvc11xx_read_regs(AFE_ADDR_R(17+GP*2),2);
		GP_value=(g_AfeRegs.R17_28.VGP[GP].VGP_H<<8)|g_AfeRegs.R17_28.VGP[GP].VGP_L;//数据还原	
		temp_voltage=GP_value * 0.1;//GP_value * _lsbVCELL *1000 单位mv
		return temp_voltage;
}


/******************************************************************************/
/**
	* @说明	电压二次校准
	* @参数	电压采样值、电池串号
	* @返回值	float 电压值
	* @注	单位mV
*/
static float CellVolSecondaryCalibrate(float value,int cellno){
	if (cellno == 0) {
		s_SecondCALI_preVcm = 0;
		s_SecondCALI_preVcell_2nd = value;
	}else {
		s_SecondCALI_preVcm += s_SecondCALI_preVcell_2nd;
		s_SecondCALI_preVcell_2nd = value / (1 + s_SecondCALI_p1 * s_SecondCALI_preVcm + s_SecondCALI_p2 * s_SecondCALI_preVcm*s_SecondCALI_preVcm);
	}
	return s_SecondCALI_preVcell_2nd;
}
/**
	* @说明	计算电池组的各个电芯电压
	* @参数	寄存器R29~R76、R109
	* @返回值	uint16_t 电压值
	* @注	单位mV
*/
float DVC11XX_Calc_VCell(uint8_t cellIndex){
	float fValue;
	uint16_t uwValue;
#ifndef	 DVC1124
	uint8_t cellMask=CellMask[cellIndex];
#else
	uint8_t cellMask=cellIndex;
#endif
	if(cellIndex>AFE_MAX_CELL_CNT-1)
		return false;

	uwValue=(g_AfeRegs.R29_76.VCELLS[cellMask].VCELL_H<<8)|g_AfeRegs.R29_76.VCELLS[cellMask].VCELL_L;
	if(g_AfeRegs.R109.CVS){ //电池电压以有符号数显示，LSB=200μV
		fValue=_lsbVCELL_signed  * (s16)uwValue;
	}else{//电池电压以无符号数显示，LSB=100μV;
		fValue=_lsbVCELL * (uint16_t)uwValue;
	}		
	fValue=CellVolSecondaryCalibrate(fValue,cellIndex); //电池二次校准

	return 	fValue*1000+0.5;//四舍五入取整（单位mV）
}	

/**
	* @说明	计算电池组总电压
	* @参数	寄存器R7、R8
	* @返回值	uint16_t 电压值
	* @注	单位mV
*/
uint32_t DVC11XX_Calc_VBAT(void){
	uint16_t uwValue = (g_AfeRegs.R7_8.VBAT_H<<8)|g_AfeRegs.R7_8.VBAT_L;
	float fValue= _lsbVCELL * 10000 * uwValue*12.8;
	return 	(uint32_t)(fValue+0.5);//四舍五入取整
}

/**
	* @说明	计算PACK管脚电压值
	* @参数	寄存器R9、R10
	* @返回值	uint16_t 电压值
	* @注 单位mV
*/
uint32_t DVC11XX_Calc_VPACK(void){
	uint16_t uwValue = (g_AfeRegs.R9_10.VPK_H<<8)|g_AfeRegs.R9_10.VPK_L;
	float fValue = _lsbVCELL * 10000 * uwValue*12.8;
	return 	(uint32_t)(fValue+0.5);//四舍五入取整
}

/**
	* @说明	计算LOAD管脚电压值
	* @参数	寄存器R11、R12
	* @返回值	uint16_t 电压值
	* @注 单位mV
*/
uint32_t DVC11XX_Calc_VLOAD(void){
	uint16_t uwValue = (g_AfeRegs.R11_12.VLD_H<<8)|g_AfeRegs.R11_12.VLD_L;
	float fValue = _lsbVCELL * 10000 * uwValue*12.8;
	return 	(uint32_t)(fValue+0.5);//四舍五入取整
}
/**
	* @说明	计算V1P8管脚电压值
	* @参数	寄存器R15、R16
	* @返回值	uint16_t 电压值
	* @注 单位mV
*/
uint16_t DVC11XX_Calc_V1P8(void){
	uint16_t uwValue=(g_AfeRegs.R15_16.V1P8_H<<8)|g_AfeRegs.R15_16.V1P8_L;
	float fValue = _lsbVCELL * 1000 * uwValue;
	return 	(uint16_t)(fValue+0.5);//四舍五入取整
}
/**
	* @说明	电芯屏蔽
	* @参数	屏蔽电芯各串号
	* @返回值	
	* @注 
*/
void CellTestClose(uint32_t cellnumber){
	if(cellnumber<=0xfffff){//u20
		g_AfeRegs.R106.CM_H=cellnumber>>12;
		g_AfeRegs.R107.CM_M=((uint16_t)cellnumber&0x0ff0)>>4;
		g_AfeRegs.R108.CM_L=(uint8_t)cellnumber&0x0f;
		while(!dvc11xx_write_regs(AFE_ADDR_R(106),3));
	}
}

/////////////////////////////////////////////////////////////////////////////


//通过过滤器CC1的采样值来计算电流 
//相关寄存器 R2~R3
float DVC11XX_Calc_CurrentWithCC1(float senseResistance_mR){
	s16 swValue=(g_AfeRegs.R2_3.CC1_H<<8)|g_AfeRegs.R2_3.CC1_L;
	return swValue*_lsbCC1*1000/senseResistance_mR; //返回电流值（单位A）
}	

static int32_t cc2ZeroCaliOffset = 0x7fffffff;
//通过过滤器CC2的采样值来计算电流 
//相关寄存器 R4~R6
float DVC11XX_Calc_CurrentWithCC2(float senseResistance_mR){
	s32 iValue=((g_AfeRegs.R4_6.CC2_H<<12)|(g_AfeRegs.R4_6.CC2_M<<4)|g_AfeRegs.R4_6.CC2_L);
	if(iValue&0x80000) 
		iValue|=0xFFF00000; //若为负数则补足32位补码
	int32_t cur_mA =  (int32_t)(iValue*_lsbCC2*1000000/senseResistance_mR);
	//printf("cur_mA = %d\n",cur_mA);
	cur_mA -=  cc2ZeroCaliOffset;
	if(abs(cur_mA) < 50){
		cur_mA = 0;
	}
	//printf("cc2ZeroCaliOffset = %d, cur_mA = %d\n", cc2ZeroCaliOffset,cur_mA);
	return (float)cur_mA;
}

/***************************************************************************************/
/**
	* @说明	中断屏蔽设置
	* @参数	uint8_t 模式
	* @返回值	
	* @注	
*/
void InterruptShield_Config(uint8_t mode){
	memset((uint8_t *)&g_AfeRegs+121,mode,1);//R121一次性写入
	dvc11xx_write_regs(AFE_ADDR_R(121), 1);
}


/******************************************************************************
                    		
******************************************************************************/

/**
	* @说明	一级放电过流配置
	* @参数	uint16_t 阈值 250-63750uv 步进 250uv
					uint16_t DLY  8-2040ms 步进 8ms
	* @返回值	成功/失败
	* @注	
*/
bool OCD1_Config(uint16_t TH,uint16_t DLY){

	TH=TH*CurrentSenseResistance_mR*1000;
	DLY=DLY*1000;
	if(TH>=250&&TH<=63750){//未超量程
		g_AfeRegs.R89.OCD1T=TH/250;
		if(DLY>=8&&DLY<=2040){
			g_AfeRegs.R91.OCD1D=DLY/8-1;
		}
		return dvc11xx_write_regs(AFE_ADDR_R(89),1)&dvc11xx_write_regs(AFE_ADDR_R(91),1);
	}else if(TH==0){
		g_AfeRegs.R89.OCD1T=0;
		return dvc11xx_write_regs(AFE_ADDR_R(89),1);
	}else
		return false;
}
/**
	* @说明	二级充电过流配置
	* @参数	uint16_t TH 4-256mv 步进4mv
			uint16_t DLY 4-1020ms 步进4ms
			bool enable enable/disable
	* @返回值	成功/失败
	* @注	
*/
bool OCD2_Config(uint16_t TH,uint16_t DLY,bool enable){//
	TH=TH*CurrentSenseResistance_mR;
	if(!enable){//关闭OCD2
		g_AfeRegs.R94.OCD2E=0;
		return dvc11xx_write_regs(AFE_ADDR_R(94),1);
	}else{
		if(TH>256){//超限按最大值算
			TH=256;
		}else{		
		if(TH>=4&&TH<=256){//未超量程
			g_AfeRegs.R94.OCD2T=TH/4-1;
			if(DLY<=1020){
				g_AfeRegs.R96.OCD2D=DLY/4-1;
			}
			g_AfeRegs.R94.OCD2E=enable;
		}}
		return dvc11xx_write_regs(AFE_ADDR_R(94),1)&dvc11xx_write_regs(AFE_ADDR_R(96),1);
	}
}
/**
	* @说明	一级充电过流配置
	* @参数	uint16_t 阈值 250-63750uv 步进 250uv
					uint16_t DLY  8-2040ms 步进 8ms
	* @返回值	成功/失败
	* @注	
*/
bool OCC1_Config(uint16_t TH,uint16_t DLY){
		
	DLY=DLY*1000;
	TH=TH*CurrentSenseResistance_mR*1000;
	
	if(TH>=250&&TH<=63750){//未超量程
		if(DLY>=8&&DLY<=2040){
			g_AfeRegs.R92.OCC1D=DLY/8-1;
		}
		g_AfeRegs.R90.OCC1T=TH/250;
		return dvc11xx_write_regs(AFE_ADDR_R(90),1)&dvc11xx_write_regs(AFE_ADDR_R(92),1);
	}else if(TH==0){//关闭
		g_AfeRegs.R90.OCC1T=0;
		return dvc11xx_write_regs(AFE_ADDR_R(90),1);
	}else
		return false;
}
/**
	* @说明	二级放电过流配置
	* @参数	uint16_t TH 4-256mv 步进4mv
					uint16_t DLY 4-1020ms 步进4ms
					bool enable enable/disable
	* @返回值	成功/失败
	* @注	
*/
bool OCC2_Config(uint16_t TH,uint16_t DLY,bool enable){//
	
	TH=TH*CurrentSenseResistance_mR;
	DLY=DLY*1000;
	if(!enable){//关闭OCC2
		g_AfeRegs.R95.OCC2E=0;
		return dvc11xx_write_regs(AFE_ADDR_R(95),1);
	}else{
		if(TH>256){
			TH=256;
		}else{
		if(TH>=4&&TH<=256){//未超量程
		g_AfeRegs.R95.OCC2T=TH/4-1;
		if(DLY<=1020){
			g_AfeRegs.R97.OCC2D=DLY/4-1;
		}
		g_AfeRegs.R95.OCC2E=enable;}}
		return dvc11xx_write_regs(AFE_ADDR_R(95),1)&dvc11xx_write_regs(AFE_ADDR_R(97),1);
	}
}

/**
	* @说明	过压配置
	* @参数	uint16_t TH 500-4095mv 步进1mv
					uint16_t DLY 200-8000ms 200-1000步进100, 1000-8000步进1000
	* @返回值	成功/失败
	* @注	
*/
bool OV_Config(uint16_t TH,uint16_t DLY){
	
	DLY =DLY*1000;
	TH=TH-500;
	if(TH>=500&&TH<=4095){
		g_AfeRegs.R112.COVT_H=TH>>4;//u12 高8位
		g_AfeRegs.R113.COVT_L=TH&0x0f;//u12 低4位
		
		if(DLY>=200&&DLY<=8000){//未超量程
			if(DLY>1000)//1s以上步进1s
			g_AfeRegs.R113.COVD=DLY/1000+7;	
			else
			g_AfeRegs.R113.COVD=DLY/100-2;	//1s以下步进100ms
		}
		return dvc11xx_write_regs(AFE_ADDR_R(112),2);
	}else{
		g_AfeRegs.R112.COVT_H=0>>4;//u12 高8位
		g_AfeRegs.R113.COVT_L=0&0x0f;//u12 低4位
		if(DLY>=200&&DLY<=8000){//未超量程
			if(DLY>1000)//1s以上步进1s
			g_AfeRegs.R113.COVD=DLY/1000+7;	
			else
			g_AfeRegs.R113.COVD=DLY/100-2;	//1s以下步进100ms
		}
		return dvc11xx_write_regs(AFE_ADDR_R(112),2);
	}
	return false;
}
/**
	* @说明	欠压配置
	* @参数	uint16_t TH 500-4595mv 步进1mv
					uint16_t DLY 200-8000ms 200-1000步进100, 1000-8000步进1000
	* @返回值	成功/失败
	* @注	
*/
bool UV_Config(uint16_t TH,uint16_t DLY){
	
	DLY =DLY*1000;
//	TH=TH-500;
	if(TH>=500&&TH<=4095){
		g_AfeRegs.R114.CUVT_H=TH>>4;//u12 高8位
		g_AfeRegs.R115.CUVT_L=TH&0x0f;//u12 低4位
		if(DLY>=200&&DLY<=8000){//未超量程
			if(DLY>1000)//1s以上步进1s
			g_AfeRegs.R115.CUVD=DLY/1000+7;	
			else
			g_AfeRegs.R115.CUVD=DLY/100-2;//1s以下步进100ms	
		}
		return dvc11xx_write_regs(AFE_ADDR_R(114),2);
	}else{
		g_AfeRegs.R114.CUVT_H=0>>4;//u12 高8位
		g_AfeRegs.R115.CUVT_L=0&0x0f;//u12 低4位
		if(DLY>=200&&DLY<=8000){//未超量程
			if(DLY>1000)//1s以上步进1s
			g_AfeRegs.R115.CUVD=DLY/1000+7;	
			else
			g_AfeRegs.R115.CUVD=DLY/100-2;//1s以下步进100ms	
		}
		return dvc11xx_write_regs(AFE_ADDR_R(114),2);
	}
	return false;

}
/**
	* @说明	放电短路配置
	* @参数	uint16_t 阈值 10-640mv 步进 10mv
					float DLY  0-1992us 步进 7.81us
	* @返回值	成功/失败
	* @注	
*/

bool SCD_Config(uint16_t TH,uint16_t DLY,bool enable){

	TH=TH*CurrentSenseResistance_mR/10;
	if(!enable){//关闭SCD
		g_AfeRegs.R98.SCDE=0;
		return dvc11xx_write_regs(AFE_ADDR_R(98),1);
	}
	else{
		if(TH>=10&&TH<=256){//未超量程
			g_AfeRegs.R98.SCDT=TH;
			if(DLY<=1992){
				g_AfeRegs.R99.SCDD=DLY/8;
			}
			g_AfeRegs.R98.SCDE=enable;
			return dvc11xx_write_regs(AFE_ADDR_R(98),2);
		}else
			return false;
	}
}

void Clear_OCD1(void){
	g_AfeRegs.R0.bitmap.OCD1 = 0;
	dvc11xx_write_regs(AFE_ADDR_R(0),1);
}

void Clear_OCD2(void){
	g_AfeRegs.R0.bitmap.OCD2 = 0;
	dvc11xx_write_regs(AFE_ADDR_R(0),1);
}

void Clear_OCC1(void){
	g_AfeRegs.R0.bitmap.OCC1 = 0;
	dvc11xx_write_regs(AFE_ADDR_R(0),1);
}

void Clear_OCC2(void){
	g_AfeRegs.R0.bitmap.OCC2 = 0;
	dvc11xx_write_regs(AFE_ADDR_R(0),1);
}

void Clear_OV(void){
	g_AfeRegs.R0.bitmap.COV = 0;
	dvc11xx_write_regs(AFE_ADDR_R(0),1);
}

void Clear_UV(void){
	g_AfeRegs.R0.bitmap.CUV = 0;
	dvc11xx_write_regs(AFE_ADDR_R(0),1);
}

void Clear_SCD(void){
	g_AfeRegs.R0.bitmap.SCD = 0;
	dvc11xx_write_regs(AFE_ADDR_R(0),1);	
}

/**************************************************************************************/

/**
	* @说明	查询充电器状态打印输出
	* @参数	
	* @返回值	
	* @注	
*/
void ChargerDetect(void){
	if(g_AfeRegs.R1.PD==1)//打印对应报警
		printf("Charger Connected! \r\n");
}

/**
	* @说明	使能负载上拉
	* @参数	
	* @返回值	
	* @注	
*/
void LoadPullUp(void){
	g_AfeRegs.R81.LDPU=1;
	dvc11xx_write_regs(AFE_ADDR_R(81), 1);
	Delay_ms(200);//上拉后等待一组AFE数据		
}

/**
	* @说明	查询充电器状态打印输出
	* @参数	
	* @返回值	
	* @注	
*/
void LoadDetect(void){
	uint16_t Vload;	
	Vload=DVC11XX_Calc_VLOAD();//计算Vload电压
	printf("Vload = %u mV\r\n", Vload);
	if(Vload>=LoadDetect_Threshold)//比较阈值2V
		printf("Load Disconnect \r\n");
	else
		printf("Load Connecting \r\n");

}

/******************************************************************************
*							断线检测驱动
**************************************************************************************/
/**
	* @说明	断线检测使能
	* @参数	
	* @返回值	
	* @注	
*/
void COW_enable(void){
	g_AfeRegs.R109.COW=1;//置位
	dvc11xx_write_regs(AFE_ADDR_R(109), 1);//写入
}

/**
	* @说明	断线检测结果打印输出
	* @参数	
	* @返回值	
	* @注	
*/
void BrokenLineDetect(void){
uint8_t i;
int uw_cellvotage[AFE_MAX_CELL_CNT];
	for(i=0;i<AFE_MAX_CELL_CNT;i++){
		uw_cellvotage[i]=DVC11XX_Calc_VCell(i);//计算各串电压
		if(uw_cellvotage[i]==0)//断线串打印输出
			printf("CELL %d Broken!\r\n",i+1);
	
	}

}

/******************************************************************************
 *			   			 AFE温度计算处理                              		
******************************************************************************/
/////////////////////////////////////////////////////////////////////////////

uint16_t Rpu=0;
const int NCP18XH103_Temp[34]={//℃
	-40,-35,-30,-25,-20,-15,-10,-5,
	0,5,10,15,20,25,30,35,
	40,45,50,55,60,65,70,75,
	80,85,90,95,100,105,110,115,
	120,125
};
const float NCP18XH103_Res[34]={//kohm
	195.652,148.171,113.347,87.559,68.237,53.65,42.406,33.892,
	27.219,22.021,17.926,14.674,12.081,10,8.315,6.948,
	5.834,4.917,4.161,3.535,3.014,2.586,2.228,1.925,
	1.669,1.452,1.268,1.11,0.974,0.858,0.758,0.672,
	0.596,0.531
};

/**
	* @说明	读取NFRT计算上拉电阻
	* @参数	
	* @返回值	
	* @注	
*/
void Read_NFRT (void){
	dvc11xx_read_regs(AFE_ADDR_R(126),1);
	Rpu=g_AfeRegs.R126.F1RT*25+6800;//欧姆
	printf("Rpu = %d ohm\r\n",Rpu);
}

/**
	* @说明	GP1管脚复用配置
	* @参数	
	* @返回值	
	* @注	
*/
void GPM_Temperature (void){
	g_AfeRegs.R116.GP1M|=0x01;		//电池温度1
	g_AfeRegs.R117.GP4M|=0x01;		//电池温度2
	dvc11xx_write_regs(AFE_ADDR_R(116),2);
	dvc11xx_write_regs(AFE_ADDR_R(117),2);
}

/**
	* @说明	芯片温度计算
	* @参数	
	* @返回值	float Tp_Value 温度值
	* @注	
*/
float DVC11XX_Calc_ChipTemp(void){
	float Tp_Value;
	uint16_t VCT=(g_AfeRegs.R13_14.VCT_H<<8)|g_AfeRegs.R13_14.VCT_L;
	Tp_Value=VCT*0.24467-271.3;
	return Tp_Value;
}

/**
	* @说明	温敏电阻采样温度计算
	* @参数	uint8_t GP 复用管脚
	* @返回值	float Tp_Value 温度值
	* @注	
*/
float DVC11XX_Calc_BatTemp(uint8_t GP){
	dvc11xx_read_regs(AFE_ADDR_R(15),16);
	float V1P8t,VGPt,Tp_Value,GP_res;
	uint8_t i,t=34;
	uint16_t V1P8=(g_AfeRegs.R15_16.V1P8_H<<8)|g_AfeRegs.R15_16.V1P8_L;
	uint16_t GPn_T=(g_AfeRegs.R17_28.VGP[GP].VGP_H<<8)|g_AfeRegs.R17_28.VGP[GP].VGP_L;
	V1P8t=V1P8*0.1;//V1P8 * _lsbVCELL *1000 单位mv
	VGPt=GPn_T*0.1;//VGP1 * _lsbVCELL *1000 单位mv
	GP_res=(VGPt/V1P8t*Rpu)/(1-VGPt/V1P8t)/1000;//GP1温敏电阻计算值 
	for(i=0;i<t;){//查表
		if(GP_res<=NCP18XH103_Res[i])
			i++;
		else 
			t=i;
	}
	Tp_Value=NCP18XH103_Temp[t]-(NCP18XH103_Res[t]-GP_res)/(NCP18XH103_Res[t]-NCP18XH103_Res[t-1])*5;//平滑处理
	
	return Tp_Value;
}

/********************************************************************************/
/**
	* @说明	均衡控制
	* @参数	u32 vlaue 均衡位
	* @返回值	
	* @注 
*/
void Balance_Contrl(uint32_t vlaue){
	if(vlaue<0xffffff){
		g_AfeRegs.R103_R105.CB[0]=vlaue>>16;
		g_AfeRegs.R103_R105.CB[1]=vlaue>>8;
		g_AfeRegs.R103_R105.CB[2]=vlaue&0xff;
		dvc11xx_write_regs(AFE_ADDR_R(103),3);//打开对应均衡位
	}
}

/******************************************************************************
								FET控制驱动
**************************************************************************************/
/**
	* @说明	预充驱动开关
	* @参数	bool 开/关
	* @返回值	成功/失败
	* @注	
*/
bool PCHG_FETControl(bool abel){
	g_AfeRegs.R81.PCHGC=abel;

	return dvc11xx_write_regs(AFE_ADDR_R(81),1);
}
/**
	* @说明	预放驱动开关
	* @参数	bool 开/关
	* @返回值	成功/失败
	* @注	
*/
bool PDSG_FETControl(bool abel){
	g_AfeRegs.R81.PDSGC=abel;

	return dvc11xx_write_regs(AFE_ADDR_R(81),1);
}

/**
	* @说明	充电驱动开关
	* @参数	uint8_t 模式
	* @返回值	成功/失败
	* @注	
*/
bool CHG_FETControl(uint8_t mode){
	if(mode==2){
		g_AfeRegs.R84.CBDM=0;
	}else if(mode==0){
		g_AfeRegs.R81.CHGC=0;
	}else if(mode==1){
		g_AfeRegs.R81.CHGC=3;
	}
	
	return dvc11xx_write_regs(AFE_ADDR_R(81),4);
}

/**
	* @说明	放电驱动开关
	* @参数	uint8_t 模式
	* @返回值	成功/失败
	* @注	
*/
bool DSG_FETControl(uint8_t mode){
	if(mode==2){
		g_AfeRegs.R83.DBDM=0;
	}else if(mode==0){
		g_AfeRegs.R81.DSGC=0;
	}else if(mode==1){
		g_AfeRegs.R81.DSGC=3;
	}

	return dvc11xx_write_regs(AFE_ADDR_R(81),3);
}

/**
	* @说明	高边DSG输出模式设置
	* @参数	bool 模式
	* @返回值	成功/失败
	* @注	
*/
bool DSGM_Control(bool mode){
	g_AfeRegs.R81.DSGM=mode;

	return dvc11xx_write_regs(AFE_ADDR_R(81),1);
}

/**
	* @说明	高边DSG下拉强度设置
	* @参数	uint8_t 强度等级 0~30
	* @返回值	成功/失败
	* @注	
*/
bool DPC_Config(uint8_t DPC){
	if(DPC<31){
		g_AfeRegs.R82.DPC=DPC;
		return dvc11xx_write_regs(AFE_ADDR_R(82),1);
	}
	return false;
}
/**
	* @说明	续流保护阈值设置
	* @参数	uint16_t 保护阈值 单位 uV
	* @返回值	成功/失败
	* @注	保护阈值=BDPT*40uV
*/
bool BDPT_Config(uint16_t value){
	
	if(value<=10200){
		g_AfeRegs.R102.BDPT=value/40;
		return dvc11xx_write_regs(AFE_ADDR_R(102),1);
	}else
		return false;
}
/**
	* @说明	电荷泵输出设置
	* @参数	uint8_t 模式
	* @返回值	成功/失败
	* @注	
*/
bool ChargePump_Control(uint8_t mode){
	g_AfeRegs.R109.CPVS=mode;

	return dvc11xx_write_regs(AFE_ADDR_R(109),1);
}

/**
	* @说明	高边驱动屏蔽设置
	* @参数	bool 开/关
	* @返回值	成功/失败
	* @注	保护阈值=BDPT*40uV
*/
bool HSFM_Control(bool mode){
	g_AfeRegs.R85.HSFM=mode;

	return dvc11xx_write_regs(AFE_ADDR_R(85),1);
}

static uint8_t dvc11xx_alert_flag =0;
uint8_t get_dvc11xx_alert_flag(){
	return dvc11xx_alert_flag;
}

void dvc11xx_alert_flag_clear(){
	dvc11xx_alert_flag = 0;
}

void dvc_IRQHandler(void){ 
	dvc11xx_alert_flag = 1;
}

void dvc_irq_init(void){
	hc32_pin_mode(DVC_INT_PIN,PIN_MODE_INPUT_PULLDOWN);
	hc32_pin_attach_irq(DVC_INT_PIN,PIN_IRQ_MODE_FALLING,dvc_IRQHandler);
	hc32_pin_irq_enable(DVC_INT_PIN,true);

}

void FET_Open(void){
	g_AfeRegs.R81.CHGC	=	0x3;
	g_AfeRegs.R81.DSGC	=	0x3;
	dvc11xx_write_regs(AFE_ADDR_R(81),1);	
}

void GPn_ModeConfig(bool mode){
	memset((uint8_t *)&g_AfeRegs+116,0,2);//GPn数据位 初始化为0
	GPM_Temperature();
	GP2_ModeConfig(0x07);
	GP3_ModeConfig(0x06);
	GP5_ModeConfig(0x07);
	GP6_ModeConfig(0x07);
	
	//FET_Open();//打开充放电
}

void dvc11xx_setVadcPeriod(DVC11xx_VadcPeriod period){
	g_AfeRegs.R110.VAMP = period;
	dvc11xx_write_regs(AFE_ADDR_R(110),1);
}

void dvc11xx_shutdown(void){
	g_AfeRegs.R1.CST = 0x0f;
	dvc11xx_write_regs(AFE_ADDR_R(1),1);
}

void dvc11xx_sleep(void){
	g_AfeRegs.R1.CST = 0x0e;
	dvc11xx_write_regs(AFE_ADDR_R(1),1);
}



void Set_Bat_Shielding(uint8_t BatNum){
#ifdef	 DVC1117
	switch(BatNum){
		case 5:{
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xff;
			g_AfeRegs.R108.CM_L = 0x0e;
		}break;
		case 6:{
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xff;
			g_AfeRegs.R108.CM_L = 0x0c;
			
		}break;
		case 7:{
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xff;
			g_AfeRegs.R108.CM_L = 0x08;
			
		}break;
		case 8:{
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xff;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 9:{	
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xfe;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 10:{	
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xfc;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 11:{
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xf4;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 12:{
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0xd4;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 13:{
			g_AfeRegs.R106.CM_H = 0Xff;
			g_AfeRegs.R107.CM_M = 0x54;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 14:{
			g_AfeRegs.R106.CM_H = 0Xfd;
			g_AfeRegs.R107.CM_M = 0x54;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 15:{
			g_AfeRegs.R106.CM_H = 0Xf5;
			g_AfeRegs.R107.CM_M = 0x54;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 16:{
			g_AfeRegs.R106.CM_H = 0Xd5;
			g_AfeRegs.R107.CM_M = 0x54;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
		case 17:{
			g_AfeRegs.R106.CM_H = 0X55;
			g_AfeRegs.R107.CM_M = 0x54;
			g_AfeRegs.R108.CM_L = 0x00;
		}break;
	}
#endif
#ifdef DVC1124
	unsigned char i =0;
	uint32_t shieldVolProt = 0xffffffff;//电池保护屏蔽控制位
	if(BatNum<=24){
		for(i=5;i<=BatNum;i++){
			shieldVolProt &= (~(1u<< (i-1)));
		}
		g_AfeRegs.R106.CM_H = (shieldVolProt>>16) & 0xff;
		g_AfeRegs.R107.CM_M = (shieldVolProt>>8) & 0xff;
		g_AfeRegs.R108.CM_L = (shieldVolProt>>4) & 0xff;
//		printf("shieldVolProt = %02x\n",shieldVolProt);
	}else{
		printf("set BATNum error,exceed 24s\n");
	}	
#endif
	dvc11xx_write_regs(AFE_ADDR_R(106),3);
}
	
void DVC11XX_init(void){
	dvc_irq_init(); 
	drv11xx_init();
	while(!DVC11XX_InitRegs()){
		iwdt_feed_dog();
		Delay_ms(200); 
		printf("@@\n");
	};  //8. AFE芯片寄存器初始化（写入用户自定义的配置数据）
	CleanError();//写入默认值后清除警报
	printf("Initial Completed !\r\n");
	GPn_ModeConfig(1);
	Delay_ms(1000);
	while(dvc11xx_read_regs(AFE_ADDR_R(1), 1)){//如果CRC正确
		iwdt_feed_dog();
		Delay_ms(300); //发现大概1000ms后电流采集稳定
		if(g_AfeRegs.R1.CC2F == 1){//转换完成
			static int32_t last_cur_mA = 0;
			static uint8_t cur_mA_steady_cnt = 0;
			if(dvc11xx_read_regs(AFE_ADDR_R(4), 3) == true){//读取电流
				s32 iValue=((g_AfeRegs.R4_6.CC2_H<<12)|(g_AfeRegs.R4_6.CC2_M<<4)|g_AfeRegs.R4_6.CC2_L);
				if(iValue&0x80000) 
					iValue|=0xFFF00000; //若为负数则补足32位补码
				int32_t cur_mA = (int32_t)(iValue*_lsbCC2*1000000/CurrentSenseResistance_mR);
				if(iValue&0x80000) {
					iValue|=0xFFF00000; //若为负数则补足32位补码
				}
				if(cur_mA_steady_cnt++ <= 10){
					if(abs(last_cur_mA) < abs(cur_mA)){
						last_cur_mA = cur_mA;
						cc2ZeroCaliOffset = cur_mA;
					}
				}else{
					cur_mA_steady_cnt = 0;
					break;
				}
//				printf("cur_mA = %dmA，cc2ZeroCaliOffset = %d\n",cur_mA,cc2ZeroCaliOffset);			
//				printf("dsgmos = %d,chgmos= %d\n",g_AfeRegs.R81.DSGC,g_AfeRegs.R81.CHGC);
			}
		}else{
			printf("Wait for CC2 convert done.\n");
		}
	}
}

